#include "jiekou.h"
#include "main_header.h"
#include <stdio.h>
// 生成盐值
void generate_salt(char *salt) {
  const char salt_chars[] =
      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890./";
  srand(time(NULL));
  strcat(salt, "$6$");

  for (int i = 0; i < 16; i++) {
    salt[3 + i] = salt_chars[rand() % (sizeof(salt_chars) - 1)];
  }
  salt[19] = '$';
}
// 生成密文
void generate_ciphertext(char *salt, char *passwd, char *ciphertext) {
  struct crypt_data data;
  memset(&data, 0, sizeof(data));
  char *p = crypt_r(passwd, salt, &data);
  if (p == NULL) {
    return;
  }
  strncpy(ciphertext, p, 1024);
}
int userRegister(MYSQL *db, int netfd, user_t *user) {
  train_t train;
  bzero(&train, sizeof(train));
  //接受用户名
  recvn(netfd, &train.length, sizeof(train.length));
  recvn(netfd, train.data, train.length);
  char username[1024] = {0};
  strncpy(username, train.data, train.length);
  username[train.length] = '\0';
  char sql[4096] = {0};
  //查找用户名
  snprintf(sql, sizeof(sql), "select *from user1 where username='%s'",
           username);
  const char *sql_select1 = sql;
  int count = selectUser1(sql_select1, db, user);
  strcpy(user->user[0].username, username);
  if (count != 0) {
    train.length = 0;
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    return -1;
  }
  send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
  bzero(&train, sizeof(train));
  recvn(netfd, &train.length, sizeof(train.length));
  recvn(netfd, train.data, train.length);
  char password[1024] = {0};
  strncpy(password, train.data, train.length);
  password[train.length] = '\0';
  char salt[1024] = {0};
  char password_md5[1024] = {0};
  //生成盐值
  generate_salt(salt);
  //生成密文
  generate_ciphertext(salt, password, password_md5);
  char sql_insert[4096] = {0};
  //将用户信息插入用户表中
  snprintf(sql_insert, sizeof(sql_insert),
           "insert into "
           "user1(username,salt,encrypted_password)values('%s','%s','%s')",
           username, salt, password_md5);
  const char *str = sql_insert;
  execDB(str, db);
  return 0;
}
int userLogin(MYSQL *db, int netfd, user_t *user) {
  train_t train;
  bzero(&train, sizeof(train));
  recvn(netfd, &train.length, sizeof(train.length));
  recvn(netfd, train.data, train.length);
  char username[1024] = {0};
  strcpy(username, train.data);
  username[train.length] = '\0';
  printf("接收用户名:%s\n", username);
  char sql[4096] = {0};
  //查找用户
  snprintf(sql, sizeof(sql), "select *from user1 where username='%s'",
           username);
  const char *sql_select = sql;
  //返回查到的数量
  int count = selectUser1(sql_select, db, user);
  //用户不存在，用空长度作为标志
  if (count == 0) {
    train.length = 0;
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    return -1;
  }
  bzero(&train, sizeof(train));
  strcpy(train.data, user->user[0].salt);
  train.length = strlen(train.data);
  //向客户端发送表中对应的盐值
  send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
  send(netfd, train.data, train.length, MSG_NOSIGNAL);
  bzero(&train, sizeof(train));
  //接受客户端计算的密文
  recvn(netfd, &train.length, sizeof(train.length));
  recvn(netfd, train.data, train.length);
  char password_md5[1024] = {0};
  strncpy(password_md5, train.data, train.length);
  password_md5[train.length] = '\0';
  char current_encryted_passwor1[1024] = {0};
  strcpy(current_encryted_passwor1, user->user[0].encrypted_password);
  current_encryted_passwor1[train.length] = '\0';
  //比较发过来的密文和表中密文是否一致
  if (strcmp(password_md5, current_encryted_passwor1) == 0) {
    char cmd[1024] = "登录成功";
    bzero(&train, sizeof(train));
    strcpy(train.data, cmd);
    train.length = strlen(train.data);
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    send(netfd, train.data, train.length, MSG_NOSIGNAL);
    return 0;
  } else {
    char cmd[1024] = "登录失败了";
    bzero(&train, sizeof(train));
    strcpy(train.data, cmd);
    train.length = strlen(train.data);
    //printf("train.length2=%d\n", train.length);
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    send(netfd, train.data, train.length, MSG_NOSIGNAL);
    return -1;
  }
}
